package zhanglu.family.socket.demo.busdemo.server;

import net.sf.json.JSONObject;

import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import zhanglu.family.socket.bean.ErrMsg;
import zhanglu.family.socket.bean.busbean.BusHeadBean;
import zhanglu.family.socket.bean.busbean.BusMsgBean;

/**
 * 总线消息解析器
 * 
 * @author zhanglu
 * @date 2017年3月10日
 */
public class BusHandler extends IoHandlerAdapter {
    private static Logger logger = LoggerFactory.getLogger(BusHandler.class);

    /**
     * sessionCreated:当一个新的连接建立时，由I/O processor thread调用；
     * 
     */
    // @Override
    // public void sessionCreated(IoSession session) throws Exception {
    //
    // logger.info("客户端:连接创建：" + session.getLocalAddress() + "--" +
    // session.getRemoteAddress());
    //
    // super.sessionCreated(session);
    // }

    /**
     * sessionOpened:当连接打开是调用
     */
    // @Override
    // public void sessionOpened(IoSession session) throws Exception {
    //
    // logger.info("客户端:连接打开：" + session.getRemoteAddress());
    //
    // super.sessionOpened(session);
    // }

    /**
     * messageReceived:当接收了一个消息时调用,这个也是最重要的
     */
    @Override
    public void messageReceived(IoSession session, Object message) throws Exception {

        JSONObject json = JSONObject.fromObject(message);

        BusMsgBean msg = (BusMsgBean) JSONObject.toBean(json, BusMsgBean.class);
        BusHeadBean head = msg.getHead();

        if (null != head) {
            long headId = head.getHeadId();
            if (headId == -1) {// 注册协议
                long sessionSequence = head.getSessionSequence();
                RegisterBus.registerMap.put(sessionSequence, session);

                logger.info("客户端" + sessionSequence + "注册完毕");
            } else {// 转发消息
                long targetSession = head.getTargetSession();

                IoSession target = RegisterBus.registerMap.get(targetSession);
                if (null != target) {
                    target.write(message);
                } else if (target == null && msg.getErrMsg() == ErrMsg.WAIT) {// 只有同步消息的时候。也就是wait等待状态的时候，会将目标没上线的状态传回
                    msg.setErrMsg(ErrMsg.NOTARGETSESSION);

                    JSONObject results = JSONObject.fromObject(msg);
                    session.write(results.toString());
                }
            }

        }
    }

    /**
     * sessionIdle:当连接进入空闲状态时调用
     */
    @Override
    public void sessionIdle(IoSession session, IdleStatus status) throws Exception {

        // logger.info("进入空闲时间，喝杯茶");

    }

    /**
     * sessionClosed:当连接关闭时调用
     */
    @Override
    public void sessionClosed(IoSession session) throws Exception {

        logger.info("有一个客户端断开连接....." + session.getRemoteAddress());

        removeSession(session);
    }

    /**
     * exceptionCaught:当实现IoHandler的类抛出异常时调用
     */
    @Override
    public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
        logger.info("某进程可能非法关闭");
        removeSession(session);
    }

    /**
     * 删除存放的连接
     * 
     * @param session
     *            连接
     */
    public void removeSession(IoSession session) {
        for (long key : RegisterBus.registerMap.keySet()) {
            if (RegisterBus.registerMap.get(key) == session) {
                RegisterBus.registerMap.remove(key);
                logger.info("已经删除身份为" + key + "的客户端");
            }
        }
    }
}
